import { Map, View } from 'ol'
import * as olProj from 'ol/proj'
import * as olExtent from 'ol/extent'
import { defaults } from 'ol/control/defaults'
import TileGrid from 'ol/tilegrid/TileGrid'
import TileLayer from 'ol/layer/Tile'
import XYZ from 'ol/source/XYZ'
import TileWMS from 'ol/source/TileWMS'
import WKT from 'ol/format/WKT'
import VectorLayer from 'ol/layer/Vector'
import VectorSource from 'ol/source/Vector'
import { Style, Icon, Stroke, Circle, Fill, Text } from 'ol/style'
import request_map from '@/utils/request_map'

let map
let wmsLayerGrassland
let wmsLayerPasture
const initMap = (mapSource) => {
  var tileLayer = new TileLayer({
    title: '天地图影像图层',
    source: getOptional(
      'https://t4.tianditu.gov.cn/DataServer?T=img_c&tk=ea2cc24b26c014afd2ff89223a89399a&x={x}&y={y}&l={z}'
    )
  })

  var tileMark = new TileLayer({
    title: '天地图影像境界图层',
    source: getOptional(
      'https://t4.tianditu.gov.cn/DataServer?T=ibo_c&tk=ea2cc24b26c014afd2ff89223a89399a&x={x}&y={y}&l={z}'
    )
  })

  var tileMarks = new TileLayer({
    title: '天地图影像注记图层',
    source: getOptional(
      'https://t4.tianditu.gov.cn/DataServer?T=cia_c&tk=ea2cc24b26c014afd2ff89223a89399a&x={x}&y={y}&l={z}'
    )
  })

  var layers
  layers = [tileLayer, tileMark, tileMarks]
  //  创建地图对象
  map = new Map({
    target: mapSource, // 地图容器 对应id
    layers: layers, // 图层
    view: new View({ // 视图
      projection: 'EPSG:4326',
      // 定位
      center: [102.5, 32.5],
      zoom: 8,
      maxZoom: 18,
      minZoom: 1
    }),
    // 地图自带控件，这里我们不需要，后续自己做类似功能
    controls: new defaults({
      zoom: false,
      rotate: false
    })
  })
  console.log(map)
  return map
}
const tileLayerFn = () => {
  var tileLayer = new TileLayer({
    title: '天地图影像图层',
    source: getOptional(
      'https://t4.tianditu.gov.cn/DataServer?T=img_c&tk=ea2cc24b26c014afd2ff89223a89399a&x={x}&y={y}&l={z}'
    )
  })

  var tileMark = new TileLayer({
    title: '天地图影像境界图层',
    source: getOptional(
      'https://t4.tianditu.gov.cn/DataServer?T=ibo_c&tk=ea2cc24b26c014afd2ff89223a89399a&x={x}&y={y}&l={z}'
    )
  })

  var tileMarks = new TileLayer({
    title: '天地图影像注记图层',
    source: getOptional(
      'https://t4.tianditu.gov.cn/DataServer?T=cia_c&tk=ea2cc24b26c014afd2ff89223a89399a&x={x}&y={y}&l={z}'
    )
  })

  return [tileLayer, tileMark, tileMarks]
}
const requestMap = (url) => {
  console.log(url)
  return request_map({
    url,
    methods: 'GET',
    header: {
      'Accept': 'application/json',
      'Content-Type': 'application/json; charset=utf-8'
    }
  })
}
const addGrasslandLayer = () => {
  const params = {
    'LAYERS': 'ne:t_grassland_result',
    'SERVICE': 'WMS',
    'VERSION': '1.1.0',
    'REQUEST': 'GetMap',
    'FORMAT': 'image/png',
    'TRANSPARENT': true,
    'exceptions': 'application/openlayers',
    // 'CQL_FILTER':"area_code like '513233205000%'",
    'SRS': 'EPSG:4326',
    'WIDTH': 501,
    'HEIGHT': 768,
    // 'STYLE':styles,
    'BBOX': [102.45918273925781, 32.23388671875, 103.14720153808594,
      33.28857421875]
  }

  const wmsSource = new TileWMS({
    url: 'https://common.qklny.cn/geoserver/ne/wms',
    params,
    serverType: 'geoserver',
    transition: 0

  })
  wmsLayerGrassland = new TileLayer({
    name: 'grassland',
    source: wmsSource,
    zIndex: 1
  })
  map.addLayer(wmsLayerGrassland)
}
const removeGrasslandLayer = () => {
  map.removeLayer(wmsLayerGrassland)
}
const addPastureLayer = () => {
  const params = {
    'LAYERS': 'ne:t_pasture_grassland',
    'SERVICE': 'WMS',
    'VERSION': '1.1.0',
    'REQUEST': 'GetMap',
    'FORMAT': 'image/png',
    'TRANSPARENT': true,
    'exceptions': 'application/openlayers',
    // 'CQL_FILTER':"area_code like '513233205000%'",
    'SRS': 'EPSG:4326',
    'WIDTH': 501,
    'HEIGHT': 768,
    // 'STYLE':styles,
    'BBOX': [102.45918273925781, 32.23388671875, 103.14720153808594,
      33.28857421875]
  }

  const wmsSource = new TileWMS({
    url: 'https://common.qklny.cn/geoserver/ne/wms',
    params,
    serverType: 'geoserver',
    transition: 0

  })
  wmsLayerPasture = new TileLayer({
    name: 'pasture',
    source: wmsSource,
    zIndex: 2
  })
  map.addLayer(wmsLayerPasture)
}
const removePastureLayer = () => {
  map.removeLayer(wmsLayerPasture)
}
const getOptional = (url) => {
  const projection = olProj.get('EPSG:4326')
  const projectionExtent = projection.getExtent()
  const size = olExtent.getWidth(projectionExtent) / 256
  return new XYZ({
    crossOrigin: 'anonymous',
    wrapX: true,
    // 切片xyz获取方法
    tileUrlFunction: function(tileCoord) {
      const z = tileCoord[0]
      const x = tileCoord[1]
      const y = tileCoord[2]
      const completeUrl = url.replace('{z}', z.toString())
        .replace('{y}', y.toString())
        .replace('{x}', x.toString())
      return completeUrl
    },
    // 坐标系
    projection: projection,
    tileGrid: new TileGrid({
      origin: olExtent.getTopLeft(projectionExtent),
      tileSize: [256, 256],
      // 分辨率数组 天地图为 1.40625
      // resolutions: getResolutions(1.40625, 22)
      resolutions: getResolutionsExpert(size)
    })
  })
}
const getResolutionsExpert = (size) => {
  const resolutions = new Array(18)
  const matrixIds = new Array(18)
  for (let z = 0; z < 19; ++z) {
    // 分辨率
    resolutions[z] = size / Math.pow(2, z)
    // 放大等级
    matrixIds[z] = z
  }
  return resolutions
}
const getFeatureByWKT = (item, sourceCode, targetCode) => {
  try {
    const view = map.getView()
    if (!item.wkt && !item.geom) {
      return null
    }
    // 数据格式类型
    const format = new WKT()

    const feature = format.readFeature(item.wkt || item.geom, {
      featureProjection: targetCode || view.getProjection(),
      dataProjection: sourceCode || view.getProjection()
    })
    feature.id = item.id
    feature.item = item
    feature.setStyle(() => {
      if (item.acreage && item.output) {
        return new Style({
          stroke: new Stroke({
            color: '#409EFF',
            width: 2
          }),
          image: new Circle({
            radius: 10,
            fill: new Fill({
              color: '#ffcc33'
            })
          }),
          fill: new Fill({
            color: 'rgba(64,158,255,.2)'
          })
          // text: new Text({
          //   font: '24px Microsoft YaHei',
          //   text: `面积：${item.acreage}亩`,
          //   // text: `面积：${item.acreage}亩\n产量：${item.output}吨`,
          //   fill: new Fill({
          //     color: '#FF4141'
          //   })
          // })
        })
      } else {
        return new Style({
          stroke: new Stroke({
            color: '#409EFF',
            width: 2
          }),
          image: new Circle({
            radius: 10,
            fill: new Fill({
              color: '#ffcc33'
            })
          }),
          fill: new Fill({
            color: 'rgba(64,158,255,.2)'
          })
        })
      }
    })
    return feature
  } catch (e) {
    return null
  }
}
const getFeatureByWKTYellow = (item, sourceCode, targetCode) => {
  try {
    const view = map.getView()
    if (!item.wkt && !item.geom) {
      return null
    }
    // 数据格式类型
    const format = new WKT()

    const feature = format.readFeature(item.wkt || item.geom, {
      featureProjection: targetCode || view.getProjection(),
      dataProjection: sourceCode || view.getProjection()
    })
    feature.id = item.id
    feature.item = item
    feature.setStyle(() => {
        return new Style({
          stroke: new Stroke({
            color: '#ffcc33',
            width: 2
          }),
          image: new Circle({
            radius: 10,
            fill: new Fill({
              color: '#ffcc33'
            })
          }),
          fill: new Fill({
            color: 'rgba(255,204,51,.2)'
          })
        })
    })
    return feature
  } catch (e) {
    return null
  }
}
const getFeatureByWKTs = (item, sourceCode, targetCode) => {
  console.log(item)
  try {
    const view = map.getView()
    if (!item.wkt && !item.geom) {
      return null
    }
    // 数据格式类型
    const format = new WKT()

    const feature = format.readFeature(item.wkt || item.geom, {
      featureProjection: targetCode || view.getProjection(),
      dataProjection: sourceCode || view.getProjection()
    })
    feature.id = item.id
    feature.item = item
    feature.setStyle(() => {
      return new Style({
        stroke: new Stroke({
          color: '#409EFF',
          width: 2
        }),
        image: new Circle({
          radius: 10,
          fill: new Fill({
            color: '#ffcc33'
          })
        }),
        fill: new Fill({
          color: 'rgba(64,158,255,.2)'
        }),
        text: new Text({
          font: '24px Microsoft YaHei',
          text: `草地种类：${item.type === '1' ? '冬草场' : '夏草场'}\n牧草类型：${item.grassType}`,
          fill: new Fill({
            color: '#FF4141'
          })
        })
      })
    })
    return feature
  } catch (e) {
    return null
  }
}
const initVectorLayer = () => {
  // 实例化一个矢量图层Vector作为绘制层
  const source = new VectorSource()
  // 创建一个图层
  const customVectorLayer = new VectorLayer({
    source: source,
    zIndex: 2,
    // 设置样式
    style: new Style({
      image: new Icon({
        scale: 0.9,
        // src: require('../assets/images/maoniu@2x.png'),
        anchor: [0.5, 0.5], // 图标锚点
        rotateWithView: true // 与地图视图一起旋转
        // 设置子线段箭头图标样式的角度
        // rotation: -rotation // 因为角度以顺时针旋转为正值，所以前面添加负号
      })
    })
  })
  // 将绘制层添加到地图容器中
  map.addLayer(customVectorLayer)
  return customVectorLayer
}
const initVectorLayerEqu = () => {
  // 实例化一个矢量图层Vector作为绘制层
  const source = new VectorSource()
  // 创建一个图层
  const customVectorLayer = new VectorLayer({
    source: source,
    zIndex: 3,
    // 设置样式
    style: new Style({
      image: new Icon({
        scale: 0.2,
        // src: require('../assets/images/equ1.png'),
        anchor: [0.5, 0.5], // 图标锚点
        rotateWithView: true // 与地图视图一起旋转
        // 设置子线段箭头图标样式的角度
        // rotation: -rotation // 因为角度以顺时针旋转为正值，所以前面添加负号
      })
    })
  })
  // 将绘制层添加到地图容器中
  map.addLayer(customVectorLayer)
  return customVectorLayer
}
const getFeatureByWKTPoint = (wkt, sourceCode, targetCode) => {
  try {
    const view = map.getView()
    if (!wkt) {
      return null
    }
    // 数据格式类型
    const format = new WKT()

    const feature = format.readFeature(wkt, {
      featureProjection: targetCode || view.getProjection(),
      dataProjection: sourceCode || view.getProjection()
    })

    return feature
  } catch (e) {
    console.log(e)
    return null
  }
}
const wktToGeometry = (wkt) => {
  if (!wkt) {
    return
  }

  const type = wkt.match(/[a-zA-Z]+/g)
  if (!type) {
    return null
  }

  let coordinates = wkt.replace(type, '')

  coordinates = coordinates.replaceAll('(', '[')
  coordinates = coordinates.replaceAll(')', ']')
  coordinates = coordinates.replaceAll(' ', ',')
  coordinates = coordinates.slice(1)

  function coordinatesFormat(coordinates) {
    const arr = []
    if (!isArr) {
      return
    }
    for (let i = 0; i < coordinates.length; i++) {
      if (isArr(coordinates[i])) {
        coordinates[i] = coordinatesFormat(coordinates[i])
      } else {
        if (i % 2 === 0) {
          arr.push([coordinates[i + 1], coordinates[i]])
        }
        if (i === coordinates.length - 1) {
          coordinates = arr
        }
      }
    }
    return coordinates
  }

  function getType(type) {
    const newType = type.toLowerCase()

    if (newType.includes('point')) {
      return 'point'
    }

    if (newType.includes('line')) {
      return 'line'
    }

    if (newType.includes('polygon')) {
      return 'polygon'
    }

    return newType
  }

  function isArr(arr) {
    return Array.isArray(arr)
  }

  let lngLats = coordinatesFormat(JSON.parse(coordinates))

  const newType = getType(type[0])

  // 点特殊处理
  if (newType === 'point') {
    lngLats = lngLats[0]
  }

  return {
    type: newType,
    lngLats
  }
}
export default {
  initMap,
  getOptional,
  getFeatureByWKT,
  getFeatureByWKTs,
  getFeatureByWKTYellow,
  initVectorLayer,
  initVectorLayerEqu,
  getFeatureByWKTPoint,
  removePastureLayer,
  addPastureLayer,
  removeGrasslandLayer,
  addGrasslandLayer,
  requestMap,
  tileLayerFn,
  wktToGeometry
}
